package com.imooc.imoocbilibili.aop;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.imooc.imoocbilibili.annotation.ApiLimitRole;
import com.imooc.imoocbilibili.entity.AuthRole;
import com.imooc.imoocbilibili.entity.User;
import com.imooc.imoocbilibili.entity.UserRole;
import com.imooc.imoocbilibili.interceptor.ThreadUser;
import com.imooc.imoocbilibili.service.AuthRoleService;
import com.imooc.imoocbilibili.service.UserRoleService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author 江黎
 * @since 2022-04-18
 */
@Aspect
@Order(1)
@Component
public class ApiLimitRoleAspect {

    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private AuthRoleService authRoleService;

    @Pointcut("@annotation(com.imooc.imoocbilibili.annotation.ApiLimitRole)")
    public void check(){}

    // @annotation传入注解, 获取注解内的属性
    @Before("check() && @annotation(apiLimitRole)")
    public void doBefore(JoinPoint joinPoint, ApiLimitRole apiLimitRole) {
        User user = ThreadUser.getUser();
        Long userId = user.getId();

        List<UserRole> userRoles = userRoleService.list(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserid, userId));
        for (UserRole userRole : userRoles) {
            Long roleId = userRole.getRoleid();
            AuthRole authRole = authRoleService.getOne(new LambdaQueryWrapper<AuthRole>().eq(AuthRole::getId, roleId));
            userRole.setRoleCode(authRole.getCode());
        }
        String[] limitedRoleCodeList = apiLimitRole.limitedRoleCodeList();
        Set<String> limitedRoleCodeSet = new HashSet<>(Arrays.asList(limitedRoleCodeList));
        Set<String> userRoleSet = userRoles.stream().map(UserRole::getRoleCode).collect(Collectors.toSet());

        userRoleSet.retainAll(limitedRoleCodeSet);
        if (userRoleSet.size() > 0) {
            throw new RuntimeException("权限不足");
        }

    }
}
